package dhy.com.tomcat.four.core.porcessor;

import dhy.com.tomcat.four.constants.Constants;
import dhy.com.tomcat.four.request.HttpRequest;
import dhy.com.tomcat.four.request.RequestFacade;
import dhy.com.tomcat.four.response.HttpResponse;
import dhy.com.tomcat.four.response.ResponseFacade;

import javax.servlet.Servlet;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.net.URLClassLoader;
import java.net.URLStreamHandler;

/**
 * @author 大忽悠
 * @create 2022/3/6 20:09
 */
public class ServletProcessor2 {
    public void process(HttpRequest request, HttpResponse response) {
        try {
            //1.获取servlet的名字
            String uri = request.getUri();
            String serveltName = uri.substring(uri.lastIndexOf("/") + 1);
            System.out.println("servelt的名字为: "+serveltName);
            //2.创建类加载器
            URLClassLoader loader=null;
            URL[] urls = new URL[1];
            URLStreamHandler urlStreamHandler=null;
            //类路径
            File classPath=new File(Constants.WEB_ROOT);
            //资源仓库地址
            //file.getCanonicalPath: 返回标准的文件绝对路径
            //URL : 参数一: 资源协议--file,https,ftp等 参数二:主机名,http是需要 参数三:资源路径,这里填文件路径
            String respository=(new URL("file",null,classPath.getCanonicalPath()+File.separator)).toString();
            System.out.println("仓库地址为: "+respository);
            // urlStreamHandler通过资源不同的来源来决定处理的逻辑--->不同前缀来识别。比如："file :"、"http :"、"jar :"
            urls[0] = new URL(null, respository, urlStreamHandler);
            //加载指定路径下的class
            loader=new URLClassLoader(urls);
            //负责加载当前访问的servlet
            Class myclass=null;
            //这里可以直接填类名，而非全类名的条件是,类文件放在java目录下
            myclass = loader.loadClass(serveltName);

            Servlet servlet=null;
            servlet = (Servlet) myclass.newInstance();
            //执行指定servlet的方法
            //保证用户拿到手的是外观对象
            ResponseFacade responseFacade=new ResponseFacade(response);
            RequestFacade requestFacade=new RequestFacade(request);
            //这样用户就无法通过强转调用request的特殊方法了
            servlet.service((ServletRequest) requestFacade,(ServletResponse) responseFacade);

        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (ServletException e) {
            e.printStackTrace();
        }
    }
}
